#ifndef WRAP_EPOLL_H
#define WRAP_EPOLL_H

#include <cstdint>

struct epoll_event;

namespace Wrap {

constexpr int EPOLL_CTL_ADD_ = 1;
constexpr int EPOLL_CTL_DEL_ = 2;
constexpr int EPOLL_CTL_MOD_ = 3;

constexpr int EPOLL_CLOEXEC_ = 1 << 19;

int epoll_in();
int epoll_pri();
int epoll_out();
int epoll_err();
int epoll_hup();
int epoll_rdhup();

uint32_t epoll_events_(const struct epoll_event *event);
void *epoll_data_ptr_(struct epoll_event *event);

/// @see https://man7.org/linux/man-pages/man2/epoll_create.2.html
/// @return On success, these system calls return a file descriptor (a
/// nonnegative integer). On error, -1 is returned, and errno is set to
/// indicate the error.
/// @throw EINVAL Invalid value specified in @c flags.
/// @throw EMFILE The per-user limit on the number of epoll instances imposed by
/// /proc/sys/fs/epoll/max_user_instances was encountered.  See epoll(7) for
/// further details.
/// @throw EMFILE The per-process limit on the number of open file descriptors
/// has been reached.
/// @throw ENFILE The system-wide limit on the total number of open files has
/// been reached.
/// @throw ENOMEM There was insufficient memory to create the kernel object.
int epoll_create1_(int flags);

/// @see https://man7.org/linux/man-pages/man2/epoll_wait.2.html
/// @param epfd The epoll_wait() system call waits for events on the epoll(7)
/// instance referred to by the file descriptor @c epfd.
/// @param events The buffer pointed to by @c events is used to return
/// information from the ready list about file descriptors in the interest list
/// that have some events available.
/// @param maxevents Up to @c maxevents are returned by epoll_wait(). The
/// @c maxevents argument must be greater than zero.
/// @param timeout The @c timeout argument specifies the number of milliseconds
/// that epoll_wait() will block. Time is measured against the CLOCK_MONOTONIC
/// clock.
/// @return On success, epoll_wait() returns the number of file descriptors
/// ready for the requested I/O, or zero if no file descriptor became ready
/// during the requested timeout milliseconds. On failure, epoll_wait() returns
/// -1 and errno is set to indicate the error.
/// @throw EBADF @c epfd is not a valid file descriptor.
/// @throw EFAULT The memory area pointed to by events is not accessible with
/// write permissions.
/// @throw EINTR The call was interrupted by a signal handler before either (1)
/// any of the requested events occurred or (2) the @c timeout expired; see
/// signal(7).
/// @throw EINVAL @c epfd is not an epoll file descriptor, or @c maxevents is
/// less than or equal to zero.
int epoll_wait_(int epfd, struct epoll_event *events, int maxevents, int timeout);

/// @see https://man7.org/linux/man-pages/man2/epoll_ctl.2.html
/// @param epfd This system call is used to add, modify, or remove entries in
/// the interest list of the epoll(7) instance referred to by the file
/// descriptor @c epfd.
/// @param op It requests that the operation @c op be performed
/// @param fd for the target file descriptor, @c fd.
/// @param event The @c event argument describes the object linked to the file
/// descriptor @c fd.
/// @return When successful, epoll_ctl() returns zero. When an error occurs,
/// epoll_ctl() returns -1 and errno is set to indicate the error.
/// @throw EBADF @c epfd or @c fd is not a valid file descriptor.
/// @throw EEXIST @c op was EPOLL_CTL_ADD, and the supplied file descriptor @c
/// fd is already registered with this epoll instance.
/// @throw EINVAL @c epfd is not an epoll file descriptor, or @c fd is the same
/// as @c epfd, or the requested operation @c op is not supported by this
/// interface.
/// @throw EINVAL An invalid event type was specified along with EPOLLEXCLUSIVE
/// in @c event.
/// @throw EINVAL @c op was EPOLL_CTL_MOD and @c event included EPOLLEXCLUSIVE.
/// @throw EINVAL @c op was EPOLL_CTL_MOD and the EPOLLEXCLUSIVE flag has
/// previously been applied to this @c epfd, @c fd pair.
/// @throw EINVAL EPOLLEXCLUSIVE was specified in @c event and @c fd refers to
/// an epoll instance.
/// @throw ELOOP @c fd refers to an epoll instance and this EPOLL_CTL_ADD
/// operation would result in a circular loop of epoll instances monitoring one
/// another or a nesting depth of epoll instances greater than 5.
/// @throw ENOENT @c op was EPOLL_CTL_MOD or EPOLL_CTL_DEL, and @c fd is not
/// registered with this epoll instance.
/// @throw ENOMEM There was insufficient memory to handle the requested @c op
/// control operation.
/// @throw ENOSPC The limit imposed by /proc/sys/fs/epoll/max_user_watches was
/// encountered while trying to register (EPOLL_CTL_ADD) a new file descriptor
/// on an epoll instance.  See epoll(7) for further details.
/// @throw EPERM The target file @c fd does not support epoll. This error can
/// occur if @c fd refers to, for example, a regular file or a directory.
int epoll_ctl_(int epfd, int op, int fd, struct epoll_event *event);

}


#endif